﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    public class Sample01a
    {

        public class SystemClock : IHostedService
        {
            private Timer _timer;
            /// <summary>
            /// 启动异步服务
            /// </summary>
            /// <param name="cancellationToken">宿主对象就是主机对象</param>
            /// <returns></returns>
            public Task StartAsync(CancellationToken cancellationToken)
            {
                _timer = new Timer(state =>
                {
                    Console.WriteLine($"当前时间:{DateTime.Now.ToLongTimeString()}");
                }, null, 0, 1000);
                return Task.CompletedTask;
            }
            /// <summary>
            /// 停止异步服务
            /// </summary>
            /// <param name="cancellationToken"></param>
            /// <returns></returns>
            public Task StopAsync(CancellationToken cancellationToken)
            {
                _timer?.Dispose();
                return Task.CompletedTask;
            }
        }
        /// <summary>
        /// 启动主机托管任务
        /// </summary>
        public static void Start()
        {
            //主机->托管服务->IOC容器<-再依赖注入容器内
            Console.WriteLine($"每秒打印一次");
            var host = new HostBuilder()
            .ConfigureServices(collection => collection
            .AddHostedService<SystemClock>()
            //.AddSingleton<IHostedService,SystemClock>() //也可以改成注册单例的形式
            )
            .Build();
            host.Run();
        }
    }


    public class Sample02a
    {
        /// <summary>
        /// 加温度
        /// </summary>
        public interface ITemperatureCollector
        {
            int Get();
        }

        /// <summary>
        /// 湿度
        /// </summary>
        public interface IHumidityCollector
        {
            int Get();
        }
        /// <summary>
        /// 空气质量
        /// </summary>
        public interface IAirQualityCollector
        {
            int Get();
        }

        public class Collector :
            ITemperatureCollector,
            IHumidityCollector,
            IAirQualityCollector
        {
            int ITemperatureCollector.Get()
            {
                var random = new Random();
                return random.Next(0, 100);
            }

            int IHumidityCollector.Get()
            {
                var random = new Random();
                return random.Next(0, 100);
            }

            int IAirQualityCollector.Get()
            {
                var random = new Random();
                return random.Next(0, 100);
            }
        }


        public class AirEnvironmentService : IHostedService
        {
            ITemperatureCollector _temperatureCollector;
            IHumidityCollector _humidityCollector;
            IAirQualityCollector _airQualityCollector;

            Timer _timer;

            public AirEnvironmentService(ITemperatureCollector temperatureCollector,
                                         IHumidityCollector humidityCollector,
                                         IAirQualityCollector airQualitycollector
            )
            {
                _temperatureCollector = temperatureCollector;
                _humidityCollector = humidityCollector;
                _airQualityCollector = airQualitycollector;
            }

            public Task StartAsync(CancellationToken cancellationToken)
            {
                _timer = new Timer(state =>
                {
                    Console.WriteLine(
                       $"温度:{_temperatureCollector.Get(),-10}" +
                       $"湿度:{_humidityCollector.Get(),-10}" +
                       $"空气质量:{_airQualityCollector.Get(),-10}" +
                       $"时间:{DateTime.Now.ToLongTimeString()}");
                }, null, 0, 1000);
                return Task.CompletedTask;
            }

            /// <summary>
            /// 停止异步服务
            /// </summary>
            /// <param name="cancellationToken"></param>
            /// <returns></returns>
            public Task StopAsync(CancellationToken cancellationToken)
            {
                _timer?.Dispose();
                return Task.CompletedTask;
            }
        }

        /// <summary>
        /// 启动主机托管任务
        /// </summary>
        public static void Start()
        {
            //主机->托管服务->IOC容器<-再依赖注入容器内
            Console.WriteLine($"每秒打印一次");
            var co = new Collector();
            var host = new HostBuilder()
            .ConfigureServices(collection => collection
               //也可以改成注册单例的形式
               .AddSingleton<ITemperatureCollector>(co)
               .AddSingleton<IHumidityCollector>(co)
               .AddSingleton<IAirQualityCollector>(co)
               .AddHostedService<AirEnvironmentService>()
            )
            .Build();
            host.Run();
        }
    }

    public class Sample03a
    {
        /// <summary>
        /// 加温度
        /// </summary>
        public interface ITemperatureCollector
        {
            int Get();
        }

        /// <summary>
        /// 湿度
        /// </summary>
        public interface IHumidityCollector
        {
            int Get();
        }
        /// <summary>
        /// 空气质量
        /// </summary>
        public interface IAirQualityCollector
        {
            int Get();
        }

        public class Collector :
            ITemperatureCollector,
            IHumidityCollector,
            IAirQualityCollector
        {
            int ITemperatureCollector.Get()
            {
                var random = new Random();
                return random.Next(0, 100);
            }

            int IHumidityCollector.Get()
            {
                var random = new Random();
                return random.Next(0, 100);
            }

            int IAirQualityCollector.Get()
            {
                var random = new Random();
                return random.Next(0, 100);
            }
        }

        /// <summary>
        /// 环境对象
        /// </summary>
        public class AirEnvironmentoptions
        {
            public long Interval { get; set; }
        }


        public class AirEnvironmentService : IHostedService
        {
            ITemperatureCollector _temperatureCollector;
            IHumidityCollector _humidityCollector;
            IAirQualityCollector _airQualityCollector;
            AirEnvironmentoptions _options;

            Timer _timer;

            public AirEnvironmentService(ITemperatureCollector temperatureCollector,
                                         IHumidityCollector humidityCollector,
                                         IAirQualityCollector airQualitycollector,
                                         IOptions<AirEnvironmentoptions> options//利用配置对象存放
            )
            {
                _temperatureCollector = temperatureCollector;
                _humidityCollector = humidityCollector;
                _airQualityCollector = airQualitycollector;
                _options = options.Value;//使用它的值
            }

            public Task StartAsync(CancellationToken cancellationToken)
            {
                _timer = new Timer(state =>
                {
                    Console.WriteLine(
                       $"温度:{_temperatureCollector.Get(),-10}" +
                       $"湿度:{_humidityCollector.Get(),-10}" +
                       $"空气质量:{_airQualityCollector.Get(),-10}" +
                       $"时间:{DateTime.Now.ToLongTimeString()}");
                }, null, 0, _options.Interval);//这里也改了
                return Task.CompletedTask;
            }

            /// <summary>
            /// 停止异步服务
            /// </summary>
            /// <param name="cancellationToken"></param>
            /// <returns></returns>
            public Task StopAsync(CancellationToken cancellationToken)
            {
                _timer?.Dispose();
                return Task.CompletedTask;
            }
        }


        /// <summary>
        /// 启动主机托管任务
        /// </summary>
        public static void Start()
        {
            //主机->托管服务->IOC容器<-再依赖注入容器内
            Console.WriteLine($"每秒打印一次");
            var co = new Collector();
            var host = new HostBuilder()
                .ConfigureAppConfiguration(builder => builder.AddJsonFile("appsettings2.json", true, true))//通过第三个参数实现监控功能
                .ConfigureServices((context, collection) =>
                     collection   //也可以改成注册单例的形式
                    .AddSingleton<ITemperatureCollector>(co)
                    .AddSingleton<IHumidityCollector>(co)
                    .AddSingleton<IAirQualityCollector>(co)
                    .AddHostedService<AirEnvironmentService>()
                    .AddOptions()
                    .Configure<AirEnvironmentoptions>(context.Configuration.GetSection("AirEnvironment"))//json的配置节点
                )
                .Build();
            host.Run();
        }

        /// <summary>
        /// 启动主机托管任务  //用powershell启动 dotnet run /environment=Production  //Production是appsettings.Production.json
        /// </summary>
        public static void Start(string[] args)
        {
            //主机->托管服务->IOC容器<-再依赖注入容器内
            Console.WriteLine($"每秒打印一次1");
            var co = new Collector();
            var host = new HostBuilder()
                .ConfigureHostConfiguration(builder => builder.AddCommandLine(args))  //如果要通过命令栏启用配置
                .ConfigureAppConfiguration((context, builder) =>
                {
                    builder
                       //加载不同的环境文件
                       //默认存在与否都可以的
                       .AddJsonFile("appsettings2.json", true, true)//通过第三个参数实现监控功能,这个是默认的配置文件
                       .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", true, true);//通过主机环境获取环境名称
                })
                .ConfigureServices((context, collection) =>
                     collection   //也可以改成注册单例的形式
                    .AddSingleton<ITemperatureCollector>(co)
                    .AddSingleton<IHumidityCollector>(co)
                    .AddSingleton<IAirQualityCollector>(co)
                    .AddHostedService<AirEnvironmentService>()
                    .AddOptions()
                    .Configure<AirEnvironmentoptions>(context.Configuration.GetSection("AirEnvironment"))//json的配置节点
                )
                .Build();
            host.Run();
        }

    }


    public class Sample04a
    {
        /// <summary>
        /// 加温度
        /// </summary>
        public interface ITemperatureCollector
        {
            int Get();
        }

        /// <summary>
        /// 湿度
        /// </summary>
        public interface IHumidityCollector
        {
            int Get();
        }
        /// <summary>
        /// 空气质量
        /// </summary>
        public interface IAirQualityCollector
        {
            int Get();
        }

        public class Collector :
            ITemperatureCollector,
            IHumidityCollector,
            IAirQualityCollector
        {
            int ITemperatureCollector.Get()
            {
                var random = new Random();
                return random.Next(0, 100);
            }

            int IHumidityCollector.Get()
            {
                var random = new Random();
                return random.Next(0, 100);
            }

            int IAirQualityCollector.Get()
            {
                var random = new Random();
                return random.Next(0, 100);
            }
        }

        /// <summary>
        /// 环境对象
        /// </summary>
        public class AirEnvironmentoptions
        {
            public long Interval { get; set; }
        }

        /// <summary>
        /// 日志类
        /// </summary>
        public class AirEnvironmentPublisher
        {
            const string Template = "温度:{temperature, -10}" +
                                    "湿度:{humidity, -10}" +
                                    "空气质量:{airQuality, -10]" +
                                    "时间:{now}";
            Action<ILogger, int, int, int, string, Exception> _logAction;
            private readonly ILogger _logger;

            public AirEnvironmentPublisher(ILogger<AirEnvironmentPublisher> logger)
            {
                _logger = logger;
                _logAction = LoggerMessage.Define<int, int, int, string>
                    (LogLevel.Information, 0, Template);
            }
            public void Publish(int temp, int humi, int airq)
            {
                _logAction(_logger, temp, humi, airq, DateTime.Now.ToLongTimeString(), null);
            }
        }


        public class AirEnvironmentService : IHostedService
        {
            ITemperatureCollector _temperatureCollector;
            IHumidityCollector _humidityCollector;
            IAirQualityCollector _airQualityCollector;
            AirEnvironmentoptions _options;//配置对象
            AirEnvironmentPublisher _publisher;//日志
            Timer _timer;

            public AirEnvironmentService(ITemperatureCollector temperatureCollector,
                                         IHumidityCollector humidityCollector,
                                         IAirQualityCollector airQualitycollector,
                                         AirEnvironmentPublisher publisher,//日志
                                         IOptions<AirEnvironmentoptions> options//利用配置对象存放
            )
            {
                _temperatureCollector = temperatureCollector;
                _humidityCollector = humidityCollector;
                _airQualityCollector = airQualitycollector;
                _publisher = publisher; //日志
                _options = options.Value;//配置,使用它的值
            }

            public Task StartAsync(CancellationToken cancellationToken)
            {
                _timer = new Timer(state =>
                {
                    //日志
                    _publisher.Publish(
                        _temperatureCollector.Get(),
                        _humidityCollector.Get(),
                        _airQualityCollector.Get());
                }, null, 0, _options.Interval);
                return Task.CompletedTask;
            }

            /// <summary>
            /// 停止异步服务
            /// </summary>
            /// <param name="cancellationToken"></param>
            /// <returns></returns>
            public Task StopAsync(CancellationToken cancellationToken)
            {
                _timer?.Dispose();
                return Task.CompletedTask;
            }
        }


        /// <summary>
        /// 启动主机托管任务
        /// </summary>
        public static void Start()
        {
            //主机->托管服务->IOC容器<-再依赖注入容器内
            Console.WriteLine($"每秒打印一次");
            var co = new Collector();
            var host = new HostBuilder()
                .ConfigureAppConfiguration((context, builder) =>
                {
                    builder
                       //加载不同的环境文件
                       //默认存在与否都可以的
                       .AddJsonFile("appsettings2.json", true, true)//通过第三个参数实现监控功能,这个是默认的配置文件
                       .AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", true, true);//通过主机环境获取环境名称
                })
                .ConfigureServices((context, collection) =>
                     collection   //也可以改成注册单例的形式
                    .AddSingleton<ITemperatureCollector>(co)
                    .AddSingleton<IHumidityCollector>(co)
                    .AddSingleton<IAirQualityCollector>(co)
                    .AddSingleton<AirEnvironmentPublisher>()//日志
                    .AddHostedService<AirEnvironmentService>()
                    .AddOptions()
                    .Configure<AirEnvironmentoptions>(
                         context.Configuration.GetSection("AirEnvironment"))//json的配置节点
                )
                .ConfigureLogging(log => log.AddConsole())//将日志输出到控制台
                .Build();
            host.Run();
        }
    }

    partial class Program
    {
        static void Main33(string[] args)
        {
            Console.WriteLine($"啊啊啊啊");
            //Sample01a.Start();
            //Sample02a.Start();
            //Sample03a.Start();
            //Sample03a.Start(args);//用powershell启动 dotnet run /environment=Production  //Production是appsettings.Production.json
            Sample04a.Start();//日志例子运行失败了.......
            //微服务启动===注册中心==注册服务=-注销服务
        }
    }
}
